/********************************************************************* * * Copyright (C) 2004 Andrew Khan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ***************************************************************************/ package jxl.biff; import java.util.Collection; import jxl.common.Assert; import jxl.common.Logger; import jxl.CellReferenceHelper; import jxl.Range; import jxl.biff.drawing.ComboBox; import jxl.biff.drawing.Comment; import jxl.write.biff.CellValue; /** * Container for any additional cell features */ public class BaseCellFeatures { /** * The logger */ public static Logger logger = Logger.getLogger(BaseCellFeatures.class); /** * The comment */ private String comment; /** * The comment width in cells */ private double commentWidth; /** * The comment height in cells */ private double commentHeight; /** * A handle to the drawing object */ private Comment commentDrawing; /** * A handle to the combo box object */ private ComboBox comboBox; /** * The data validation settings */ private DataValiditySettingsRecord validationSettings; /** * The DV Parser used to contain the validation details */ private DVParser dvParser; /** * Indicates whether a drop down is required */ private boolean dropDown; /** * Indicates whether this cell features has data validation */ private boolean dataValidation; /** * The cell to which this is attached, and which may need to be notified */ private CellValue writableCell; // Constants private final static double defaultCommentWidth = 3; private final static double defaultCommentHeight = 4; // Validation conditions protected static class ValidationCondition { private DVParser.Condition condition; private static ValidationCondition[] types = new ValidationCondition[0]; ValidationCondition(DVParser.Condition c) { condition = c; ValidationCondition[] oldtypes = types; types = new ValidationCondition[oldtypes.length+1]; System.arraycopy(oldtypes, 0, types, 0, oldtypes.length); types[oldtypes.length] = this; } public DVParser.Condition getCondition() { return condition; } } public static final ValidationCondition BETWEEN = new ValidationCondition(DVParser.BETWEEN); public static final ValidationCondition NOT_BETWEEN = new ValidationCondition(DVParser.NOT_BETWEEN); public static final ValidationCondition EQUAL = new ValidationCondition(DVParser.EQUAL); public static final ValidationCondition NOT_EQUAL = new ValidationCondition(DVParser.NOT_EQUAL); public static final ValidationCondition GREATER_THAN = new ValidationCondition(DVParser.GREATER_THAN); public static final ValidationCondition LESS_THAN = new ValidationCondition(DVParser.LESS_THAN); public static final ValidationCondition GREATER_EQUAL = new ValidationCondition(DVParser.GREATER_EQUAL); public static final ValidationCondition LESS_EQUAL = new ValidationCondition(DVParser.LESS_EQUAL); /** * Constructor */ protected BaseCellFeatures() { } /** * Copy constructor * * @param the cell to copy */ public BaseCellFeatures(BaseCellFeatures cf) { // The comment stuff comment = cf.comment; commentWidth = cf.commentWidth; commentHeight = cf.commentHeight; // The data validation stuff. dropDown = cf.dropDown; dataValidation = cf.dataValidation; validationSettings = cf.validationSettings; // ? if (cf.dvParser != null) { dvParser = new DVParser(cf.dvParser); } } /** * Accessor for the cell comment */ protected String getComment() { return comment; } /** * Accessor for the comment width */ public double getCommentWidth() { return commentWidth; } /** * Accessor for the comment height */ public double getCommentHeight() { return commentHeight; } /** * Called by the cell when the features are added * * @param wc the writable cell */ public final void setWritableCell(CellValue wc) { writableCell = wc; } /** * Internal method to set the cell comment. Used when reading */ public void setReadComment(String s, double w, double h) { comment = s; commentWidth = w; commentHeight = h; } /** * Internal method to set the data validation. Used when reading */ public void setValidationSettings(DataValiditySettingsRecord dvsr) { Assert.verify(dvsr != null); validationSettings = dvsr; dataValidation = true; } /** * Sets the cell comment * * @param s the comment */ public void setComment(String s) { setComment(s, defaultCommentWidth, defaultCommentHeight); } /** * Sets the cell comment * * @param s the comment * @param height the height of the comment box in cells * @param width the width of the comment box in cells */ public void setComment(String s, double width, double height) { comment = s; commentWidth = width; commentHeight = height; if (commentDrawing != null) { commentDrawing.setCommentText(s); commentDrawing.setWidth(width); commentDrawing.setWidth(height); // commentDrawing is set up when trying to modify a copied cell } } /** * Removes the cell comment, if present */ public void removeComment() { // Set the comment string to be empty comment = null; // Remove the drawing from the drawing group if (commentDrawing != null) { // do not call DrawingGroup.remove() because comments are not present // on the Workbook DrawingGroup record writableCell.removeComment(commentDrawing); commentDrawing = null; } } /** * Public function which removes any data validation, if present */ public void removeDataValidation() { if (!dataValidation) { return; } // If the data validation is shared, then generate a warning DVParser dvp = getDVParser(); if (dvp.extendedCellsValidation()) { logger.warn("Cannot remove data validation from " + CellReferenceHelper.getCellReference(writableCell) + " as it is part of the shared reference " + CellReferenceHelper.getCellReference(dvp.getFirstColumn(), dvp.getFirstRow()) + "-" + CellReferenceHelper.getCellReference(dvp.getLastColumn(), dvp.getLastRow())); return; } // Remove the validation from the WritableSheet object if present writableCell.removeDataValidation(); clearValidationSettings(); } /** * Internal function which removes any data validation, including * shared ones, if present. This is called from WritableSheetImpl * in response to a call to removeDataValidation */ public void removeSharedDataValidation() { if (!dataValidation) { return; } // Remove the validation from the WritableSheet object if present writableCell.removeDataValidation(); clearValidationSettings(); } /** * Sets the comment drawing object */ public final void setCommentDrawing(Comment c) { commentDrawing = c; } /** * Accessor for the comment drawing */ public final Comment getCommentDrawing() { return commentDrawing; } /** * Gets the data validation list as a formula. Used only when reading * * @return the validation formula as a list */ public String getDataValidationList() { if (validationSettings == null) { return null; } return validationSettings.getValidationFormula(); } /** * The list of items to validate for this cell. For each object in the * collection, the toString() method will be called and the data entered * will be validated against that string * * @param c the list of valid values */ public void setDataValidationList(Collection c) { if (dataValidation && getDVParser().extendedCellsValidation()) { logger.warn("Cannot set data validation on " + CellReferenceHelper.getCellReference(writableCell) + " as it is part of a shared data validation"); return; } clearValidationSettings(); dvParser = new DVParser(c); dropDown = true; dataValidation = true; } /** * The list of items to validate for this cell in the form of a cell range. * * @param c the list of valid values */ public void setDataValidationRange(int col1, int r1, int col2, int r2) { if (dataValidation && getDVParser().extendedCellsValidation()) { logger.warn("Cannot set data validation on " + CellReferenceHelper.getCellReference(writableCell) + " as it is part of a shared data validation"); return; } clearValidationSettings(); dvParser = new DVParser(col1, r1, col2, r2); dropDown = true; dataValidation = true; } /** * Sets the data validation based upon a named range */ public void setDataValidationRange(String namedRange) { if (dataValidation && getDVParser().extendedCellsValidation()) { logger.warn("Cannot set data validation on " + CellReferenceHelper.getCellReference(writableCell) + " as it is part of a shared data validation"); return; } clearValidationSettings(); dvParser = new DVParser(namedRange); dropDown = true; dataValidation = true; } /** * Sets the data validation based upon a numerical condition */ public void setNumberValidation(double val, ValidationCondition c) { if (dataValidation && getDVParser().extendedCellsValidation()) { logger.warn("Cannot set data validation on " + CellReferenceHelper.getCellReference(writableCell) + " as it is part of a shared data validation"); return; } clearValidationSettings(); dvParser = new DVParser(val, Double.NaN, c.getCondition()); dropDown = false; dataValidation = true; } public void setNumberValidation(double val1, double val2, ValidationCondition c) { if (dataValidation && getDVParser().extendedCellsValidation()) { logger.warn("Cannot set data validation on " + CellReferenceHelper.getCellReference(writableCell) + " as it is part of a shared data validation"); return; } clearValidationSettings(); dvParser = new DVParser(val1, val2, c.getCondition()); dropDown = false; dataValidation = true; } /** * Accessor for the data validation * * @return TRUE if this has a data validation associated with it, FALSE otherwise */ public boolean hasDataValidation() { return dataValidation; } /** * Clears out any existing validation settings */ private void clearValidationSettings() { validationSettings = null; dvParser = null; dropDown = false; comboBox = null; dataValidation = false; } /** * Accessor for whether a drop down is required * * @return TRUE if this requires a drop down, FALSE otherwise */ public boolean hasDropDown() { return dropDown; } /** * Sets the combo box drawing object for list validations * * @param cb the combo box */ public void setComboBox(ComboBox cb) { comboBox = cb; } /** * Gets the dv parser */ public DVParser getDVParser() { // straightforward - this was created as a writable cell if (dvParser != null) { return dvParser; } // this was copied from a readable cell, and then copied again if (validationSettings != null) { dvParser = new DVParser(validationSettings.getDVParser()); return dvParser; } return null; // keep the compiler happy } /** * Use the same data validation logic as the specified cell features * * @param cf the data validation to reuse */ public void shareDataValidation(BaseCellFeatures source) { if (dataValidation) { logger.warn("Attempting to share a data validation on cell " + CellReferenceHelper.getCellReference(writableCell) + " which already has a data validation"); return; } clearValidationSettings(); dvParser = source.getDVParser(); validationSettings = null; dataValidation = true; dropDown = source.dropDown; comboBox = source.comboBox; } /** * Gets the range of cells to which the data validation applies. If the * validation applies to just this cell, this will be reflected in the * returned range * * @return the range to which the same validation extends, or NULL if this * cell doesn't have a validation */ public Range getSharedDataValidationRange() { if (!dataValidation) { return null; } DVParser dvp = getDVParser(); return new SheetRangeImpl(writableCell.getSheet(), dvp.getFirstColumn(), dvp.getFirstRow(), dvp.getLastColumn(), dvp.getLastRow()); } }